//---------------------------------------------------------------------------------
//嵌套语法
nav {
  ul {margin: 0;padding: 0;list-style: none;}
  li { display: inline-block; }
  a {display: block;padding: 6px 12px;text-decoration: none;}
}

//编译后
nav ul {margin: 0;padding: 0;list-style: none; }
nav li {display: inline-block; }
nav a {display: block;padding: 6px 12px;text-decoration: none; } 
  
//---------------------------------------------------------------------------------

//引用父选择器:&
a {
  font-weight: bold;
  text-decoration: none;
  &:hover { text-decoration: underline; }
  body.firefox & { font-weight: normal; }
}
//编译为：
a{font-weight:700;text-decoration:none}
a:hover{text-decoration:underline}
body.firefox a{font-weight:400}
    
//---------------------------------------------------------------------------------

//&将替换为呈现在CSS文件中的父选择器。这意味着，如果你有一个多层嵌套的规则，父选择器将在被&替换之前完全分解。 
nav {
  a {
    color: red;

    header & {color:green;}
    
    & span {color:blue;}
  }  
} 
//编译为:nav a 会提前分解（实际上nav a是永远绑定在一起）
nav a{color:red}
header nav a{color:green}
nav a span{color:#00f}

//---------------------------------------------------------------------------------

//&也可以将父级作为前缀，但不可后缀
#main {
  color: black;
  &-sidebar { border: 1px solid; }
}
//编译为：
#main{color:#000}
#main-sidebar{border:1px solid}

//---------------------------------------------------------------------------------

//申明变量
$fontSize: 12px;
body{font-size:$fontSize;}

//编译后的css代码：
body{font-size:12px;}

//---------------------------------------------------------------------------------

//属性嵌套
//CSS 有一些属性前缀相同，只是后缀不一样，比如：border-top/border-right，与这个类似的还有 margin、padding、font 等属性。
//假设你的样式中用到了：
.box {
    border-top: 1px solid red;
    border-bottom: 1px solid green;
}
//在 Sass 中我们可以这样写：
.box {
  border: {
   top: 1px solid red;
   bottom: 1px solid green;
  }
}

//font
.funky {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
}
//编译为：
.funky {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold; }
  
//---------------------------------------------------------------------------------

//伪类嵌套和属性嵌套非常类似，只不过他需要借助`&`符号一起配合使用。我们就拿经典的“clearfix”为例吧：

.clearfix{
&:before,&:after {content:"";display: table;}
&:after {clear:both;overflow: hidden;}
}
//编译出来的 CSS：
clearfix:before, .clearfix:after {content: "";display: table;}
.clearfix:after {clear: both;overflow: hidden;}

//---------------------------------------------------------------------------------

//默认变量
//sass 的默认变量仅需要在值后面加上 !default 即可。

$baseLineHeight:1.5 !default;
body{line-height: $baseLineHeight; }

//编译后的css代码：
body{line-height:1.5;}

//sass 的默认变量一般是用来设置默认值，然后根据需求来覆盖的，覆盖的方式也很简单，只需要在默认变量之前重新声明下变量即可。
$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{line-height: $baseLineHeight; }

//编译后的css代码：
body{line-height:2;}
//可以看出现在编译后的 line-height 为 2，而不是我们默认的 1.5。默认变量的价值在进行组件化开发的时候会非常有用。

//---------------------------------------------------------------------------------

//全局变量与局部变量：如果在局部变量后面添加!global,代表全局变量
$color: orange !default;//定义全局变量(在选择器、函数、混合宏...的外面定义的变量为全局变量)
.block {
    color: $color;//调用全局变量
}
em {
  $color: red;//定义局部变量
  a {
    $color2: blue !global;//定义全局变量
    color: $color;//调用局部变量
  }
}
span {
  color: $color2;//调用全局变量
}

//css 的结果：
.block{color:orange}
em a{color:red}
span{color:#00f}

//---------------------------------------------------------------------------------

//混合宏-类似于复用组件
//在 Sass 中通过 @mixin 关键词声明了一个混合宏，那么在实际调用中，其匹配了一个关键词“@include”来调用声明好的混合宏。
//例如在你的样式中定义了一个圆角的混合宏“border-radius”:
@mixin border-radius{-webkit-border-radius: 3px;border-radius: 3px;}
//在一个按钮中要调用定义好的混合宏“border-radius”，可以这样使用：
button {
    @include border-radius;
}
//这个时候编译出来的 CSS:编译出来的css只显示混合宏的样式表，不显示混合宏名称，名称只作为调用时使用
button{-webkit-border-radius:3px;border-radius:3px}

//---------------------------------------------------------------------------------

//混合宏传参

//A) 传一个不带值的参数
@mixin border-radius($radius){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}
//在调用的时候可以给这个混合宏传一个参数值：
.box {
  @include border-radius(3px);
}
//编译出来的 CSS:
.box {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

//---------------------------------------------------------------------------------

//B) 传带值的参数（值相当于默认值，可修改）
@mixin border-radius($radius:3px){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}
//在调用类似这样的混合宏时，会多有一个机会
//假设你的页面中的圆角很多地方都是“3px”的圆角，那么这个时候只需要调用默认的混合宏“border-radius”:
.btn {
  @include border-radius;
}
//编译出来的 CSS:
.btn {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}
//但有的时候，页面中有些元素的圆角值不一样，那么可以随机给混合宏传值，如：
.box {
  @include border-radius(50%);
}
//编译出来的 CSS:
.box {
  -webkit-border-radius: 50%;
  border-radius: 50%;
}

//---------------------------------------------------------------------------------

//C) Sass 混合宏除了能传一个参数之外，还可以传多个参数，如：
@mixin center($width,$height){
  width: $width;
  height: $height;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -($height) / 2;
  margin-left: -($width) / 2;
}
//在混合宏“center”就传了多个参数。在实际调用和其调用其他混合宏是一样的：
.box-center {
  @include center(500px,300px);
}
//编译出来 CSS:
.box-center {
  width: 500px;
  height: 300px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -150px;
  margin-left: -250px;
}

//---------------------------------------------------------------------------------

//有一个特别的参数：可变参数“…”。当混合宏传的参数过多之时，可以使用其来替代，如：
@mixin box-shadow($shadows...) {
      -moz-box-shadow: $shadows;
      -webkit-box-shadow: $shadows;
      box-shadow: $shadows;
}
//调用
.shadows {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
//编译为：
.shadows {
  -moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}

//可变参数可以注入函数，判断参数的数量
@mixin box-shadow($shadows...){
  @if length($shadows) >= 1 {
    -webkit-box-shadow: $shadows;
    box-shadow: $shadows;
  } @else {
    $shadows: 0 0 2px #555;
    -webkit-box-shadow: $shadows;
    box-shadow: $shadows;
  }
}
//如上代码意为：当存在参数时，按参数来，没有参数时给出默认值
//在实际调用中：
.box {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
//编译出来的CSS:
.box {
  -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}

//---------------------------------------------------------------------------------

//传递内容块到混合宏
//样式内容块可以传递到任何 @content 指令的位置。这使得可以定义抽象 关联到选择器和指令的解析。
@mixin apply-to-ie6-only {
  * html {
    @content;
  }
}
@include apply-to-ie6-only {
  #logo {
    background-image: url(/logo.gif);
  }
}
//生成:相当于嵌套了一个内容块
* html #logo {
  background-image: url(/logo.gif);
}

//---------------------------------------------------------------------------------

//混合宏简写语法（@mixin 可以用 = 表示，而 @include 可以用 + 表示）来完成：
=apply-to-ie6-only
  * html
    @content
//调用
+apply-to-ie6-only
  #logo
    background-image: url(/logo.gif)
//结果
* html #logo {background-image: url(/logo.gif);}

//---------------------------------------------------------------------------------

//混合宏的不足之处在于，当多个选择器同时使用同一个宏时，这几个选择器并不能合并，造成冗余
//sass的继承语句@extend完美解决了这一问题
.btn {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
  @extend .btn;
}

.btn-second {
  background-color: orange;
  color: #fff;
  @extend .btn;
}
//编译出来之后：
.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}
.btn-primary {
  background-color: #f36;
  color: #fff;
}
.btn-second {
  background-clor: orange;
  color: #fff;
}
//Sass可以继承类样式块中所有样式代码，而且编译出来的 CSS会将选择器合并在一起，形成组合选择器

//---------------------------------------------------------------------------------

//@extend可以扩展任何定义给单个元素的选择器，如.special.cool,  a:hover, 或 a.user[href^="http://"]。 
.hoverlink {
  @extend a:hover;
}
//同带 class 元素一样，这意味着，a:hover定义的样式同样也适用于.hoverlink。例如：
.hoverlink {
  @extend a:hover;
}
a:hover {
  text-decoration: underline;
}
//编译为：
a:hover, .hoverlink {
  text-decoration: underline; }

//与上面 .error.intrusion 的例子一样， a:hover 中所有的样式将继承给 .hoverlink，甚至包括其他使用到她的样式，例如：
.hoverlink {
  @extend a:hover;
}
.comment a.user:hover {
  font-weight: bold;
}
//编译为：
.comment a.user:hover, .comment .user.hoverlink {
  font-weight: bold; }
  
//---------------------------------------------------------------------------------

//多重扩展 (Multiple Extends)
//同一个选择器可以扩展多个选择器。这意味着，它继承了被扩展选择器的所有样式。例如：
.error {
  border: 1px #f00;
  background-color: #fdd;
}
.attention {
  font-size: 3em;
  background-color: #ff0;
}
.seriousError {
  @extend .error;
  @extend .attention;
  border-width: 3px;
}
//编译为：
.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd; }
.attention, .seriousError {
  font-size: 3em;
  background-color: #ff0; }
.seriousError {
  border-width: 3px; }
  
//---------------------------------------------------------------------------------

//链式扩展（Chaining Extends）
//一个选择器可以扩展另一个选择器，另一个选择器又扩展的第三选择器选择。 例如：
.a {
  border: 1px #f00;
  background-color: #fdd;
}
.b {
  @extend .a;
  border-width: 3px;
}
.c {
  @extend .c;
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}
//现在，带 .b 类的每个元素将包含 .a 类，而带 .c 类的每个元素不仅包含 .c类也会同时包含 .a 类，
//编译为：
.a, .b, .c {
  border: 1px #f00;
  background-color: #fdd; }
.b, .c {
  border-width: 3px; }
.c {
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%; }
  
//---------------------------------------------------------------------------------
  
//占位符%
//% 声明的代码，如果不被 @extend 调用的话，不会产生任何代码。来看一个演示：
%mt5 {
  margin-top: 5px;
}
%pt5{
  padding-top: 5px;
}
//这段代码没有被 @extend 调用，他并没有产生任何代码块，只是静静的躺在你的某个 SCSS 文件中。只有通过 @extend 调用才会产生代码：
//SCSS
%mt5 {
  margin-top: 5px;
}
%pt5{
  padding-top: 5px;
}
.btn {
  @extend %mt5;
  @extend %pt5;
}
.block {
  @extend %mt5;

  span {
    @extend %pt5;
  }
}
//编译出来的CSS
//CSS
.btn, .block {
  margin-top: 5px;
}
.btn, .block span {
  padding-top: 5px;
}
//通过 @extend 调用的占位符，编译出来的代码会将相同的代码合并在一起，让你的代码变得更为干净。

//---------------------------------------------------------------------------------

//混合宏/继承/占位符各自的优缺点

//混合宏 =
//缺点：不会自动合并相同的样式代码，造成代码的冗余，
//优点：他可以传参数，基类不会显示在css中
//使用场景：如果你的代码块中涉及到变量，建议使用混合宏来创建相同的代码块。

//继承 @extend
//缺点：不能传变量参数，且调用的基类会显示在css中
//优点：会将使用继承的代码块合并到一起，通过组合选择器的方式向大家展现
//使用场景：如果你的代码块不需要任何变量参数，而且有一个基类已在文件中存在，那么建议使用继承。

//占位符%
//缺点：不能传变量参数
//优点：基类不会在 CSS中产生任何代码，会将使用的代码块合并到一起
//使用场景：如果你的代码块不需要任何变量参数，只是存在需要复用的代码块，那么建议使用占位符。

//总结：
//如果基类不存在于文件中，只是需要复用代码块，如果有变量用混合，如果没变量用占位符
//如果只是重复调用已经存在属性的代码块，必须用继承

//---------------------------------------------------------------------------------

//可以通过 #{} 插值语法在选择器和属性名中使用 变量：
$name: foo;
$attr: border;
p.#{$name} {
      #{$attr}-color: blue;
}
//编译为：
p.foo {
  border-color: blue; }
//它也可以使用#{}插值语句把变量插入到属性值中。
//在大多数情况下，这种做可能还不如使用直接变量来的方便
//但使用 #{}意味着靠近它的运算符都将被视为纯CSS（可以避免各种运算）。 例如：
p {
  $font-size: 12px;
      $line-height: 30px;
  font: #{$font-size}/#{$line-height};
}
//编译为：
p {
  font: 12px/30px; }

//更复杂的插值#{}
$properties: (margin, padding);
@mixin set-value($side, $value) {
    @each $prop in $properties {
        #{$prop}-#{$side}: $value;
    }
}
.login-box {
    @include set-value(top, 14px);
}
//它可以让变量和属性工作的很完美，上面的代码编译成 CSS：
.login-box {
    margin-top: 14px;
    padding-top: 14px;
}
//当你想设置属性值的时候你可以使用字符串插入进来。另一个有用的用法是构建一个选择器。可以这样使用：
@mixin generate-sizes($class, $small, $medium, $big) {
    .#{$class}-small { font-size: $small; }
    .#{$class}-medium { font-size: $medium; }
    .#{$class}-big { font-size: $big; }
}
@include generate-sizes("header-text", 12px, 20px, 40px);
//编译出来的 CSS:
.header-text-small { font-size: 12px; }
.header-text-medium { font-size: 20px; }
.header-text-big { font-size: 40px; }

//使用 @extend 中使用插值。例如：
%updated-status {
    margin-top: 20px;
    background: #F00;
}
.selected-status {
    font-weight: bold;
}
$flag: "status";
.navigation {
    @extend %updated-#{$flag};
    @extend .selected-#{$flag};
}
//动态的插入 .class 和  % 。当然他们不能接受像 mixin 这样的参数，上面的代码编译出来的 CSS:
.navigation {
    margin-top: 20px;
    background: #F00;
}
.selected-status, .navigation {
    font-weight: bold;
}

//---------------------------------------------------------------------------------

//值列表
//所谓值列表 (lists) 是指 Sass 如何处理 CSS 中： 
margin: 10px 15px 0 0
//或者： 
font-face: Helvetica, Arial, sans-serif
//像上面这样通过空格或者逗号分隔的一系列的值。
//事实上，独立的值也被视为值列表——只包含一个值的值列表。
//Sass列表函数：
//nth函数（nth function） 可以直接访问值列表中的某一项；
//join函数（join function） 可以将多个值列表连结在一起；
//append函数（append function） 可以在值列表中添加值； 
//@each规则（@each rule） 则能够给值列表中的每个项目添加样式。

//---------------------------------------------------------------------------------

//加法运算
//加法运算是 Sass 中运算中的一种，在变量或属性中都可以做加法运算。如：
.box {width: 20px + 8in;}
//编译出来的 CSS:
.box {width: 788px;}

//---------------------------------------------------------------------------------

//减法运算和加法运算类似，我们通过一个简单的示例来做阐述：
$full-width: 960px;
$sidebar-width: 200px;
.content {width: $full-width -  $sidebar-width;}

//编译出来的 CSS 如下：
.content {width: 760px;}

//---------------------------------------------------------------------------------

//乘法运算时，两个值单位相同时，只需要为一个数值提供单位即可。
.box {width: 10px * 2;}

//---------------------------------------------------------------------------------

//除法运算
//"/"符号被当作除法运算符时有以下几种情况：
//如果数值或它的任意部分是存储在一个变量中或是函数的返回值。
//如果数值被圆括号包围。
//如果数值是另一个数学表达式的一部分。
p {
  font: 10px/8px;             // 纯 CSS，不是除法运算
  $width: 1000px;
  width: $width/2;            // 使用了变量，是除法运算
  width: round(1.5)/2;        // 使用了函数，是除法运算
  height: (500px/2);          // 使用了圆括号，是除法运算
  margin-left: 5px + 8px/2px; // 使用了加（+）号，是除法运算
}
//编译出来的CSS
p {
  font: 10px/8px;
  width: 500px;
  height: 250px;
  margin-left: 9px;
 }
 
//---------------------------------------------------------------------------------
 
//颜色运算
//所有算数运算都支持颜色值，并且是分段运算的。也就是说，红、绿和蓝各颜色分段单独进行运算。如：
p {color: #010203 + #040506;}
//计算公式为 01 + 04 = 05、02 + 05 = 07 和 03 + 06 = 09， 并且被合成为：
//如此编译出来的 CSS 为：
p {color: #050709;}
//算数运算也能将数字和颜色值 一起运算，同样也是分段运算的。如：
p {color: #010203 * 2;}
//计算公式为 01 * 2 = 02、02 * 2 = 04 和 03 * 2 = 06， 并且被合成为：
p {color: #020406;}

//---------------------------------------------------------------------------------

//字符运算
//在 Sass 中可以通过加法符号“+”来对字符串进行连接。例如：
$content: "Hello" + "" + "Sass!";
.box:before {content: " #{$content} ";}
//编译出来的CSS：
.box:before {content: " Hello Sass! ";}
//除了在变量中做字符连接运算之外，还可以直接通过 +，把字符连接在一起：
div {cursor: e + -resize;}
//编译出来的CSS:
div {cursor: e-resize;}
//注意，如果有引号的字符串被添加了一个没有引号的字符串 （也就是，带引号的字符串在 + 符号左侧）， 结果会是一个有引号的字符串。 
//同样的，如果一个没有引号的字符串被添加了一个有引号的字符串 （没有引号的字符串在 + 符号左侧）， 结果将是一个没有引号的字符串。 例如：
p:before {
  content: "Foo " + Bar;
  font-family: sans- + "serif";
}
//编译出来的 CSS：
p:before {
  content: "Foo Bar";
  font-family: sans-serif; }